﻿using CommonServiceLocator;
using Jn698._45GWTool.Communication;
using Jn698._45GWTool.Models;
using Jn698._45GWTool.ModelViews;
using Jn698._45GWTool.ServiceReference1;
using Jn698._45GWTool.Services;
using Jn698._45GWTool.ViewModels.Controls;
using Jn698._45Tool.Service;
using nblTool.utils;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using WebFirst.Entities;
using WindowsFormsApp1.Utils;

namespace Communication
{
    public class AnalysisMessage
    {
        public static int analysisPoint = 0;
        private static EnumInfoService enumInfoService = new EnumInfoService();
        private static DataAccessResultService dataAccessResultService = new DataAccessResultService();
        private static OIService oIService = new OIService();
        /// <summary>
        /// 获取698有效帧
        /// </summary>
        /// <param name="frame"></param>
        /// <returns></returns>
        public static byte[] GetValidFrameByte(byte[] frame)
        {
            if (frame == null)
            {
                return null;
            }
            int len = frame.Length;
            byte[] recivedata = new byte[len];
            int rcvdatalen = 0;
            int step = 0;
            try
            {
                for (int i = 0; i < len; i++)
                {
                    if (frame[i] == 0x68 && step == 0)
                    {
                        recivedata[rcvdatalen++] = frame[i];
                        step = 1;
                        continue;

                    }
                    else if (frame[i] == 0x16)
                    {
                        if (step == 1)
                        {
                            recivedata[rcvdatalen++] = frame[i];
                            short frameLen = BitConverter.ToInt16(new byte[] { recivedata[1], recivedata[2] }, 0);
                            if (frameLen == rcvdatalen - 2)
                            {
                                step = 2;
                                break;
                            }

                            continue;
                        }
                    }
                    else if (step == 1)
                    {
                        recivedata[rcvdatalen++] = frame[i];
                    }
                }
                if (step == 2)
                {
                    return recivedata;
                }
            }
            catch (Exception e)
            {

                return null;
            }

            return null;
        }
        private static string GetOADInfo(byte[] frame)
        {
            StringBuilder sb = new StringBuilder();
            //记录型对象属性描述符    	OAD
            sb.Append("对象属性描述符：");
            string OI = "";
            string OAD = "";
            int attributeID = 0;
            int index = 0;
            string Oiname = "";
            for (int i = 0; i < 4; i++)
            {
                if (i < 2)
                {
                    OI += frame[analysisPoint].ToString("X2");
                }
                else if (i == 2)
                {
                    attributeID = frame[analysisPoint];
                }
                else
                {
                    index = frame[analysisPoint];
                }
                OAD += frame[analysisPoint].ToString("X2");
                sb.Append(frame[analysisPoint].ToString("X2"));
                analysisPoint++;
            }
            var OiInfo = oIService.SelectNameByOI(OI);
            if (OiInfo != null)
            {
                var l = SqlSugarHelper.Db.Queryable<ClassAttribute>().Where(c => c.MAttribute == attributeID).Where(c => c.MClass == OiInfo.MIC).Select(c => c.MName).ToList();
                if (l.Count > 0)
                {
                    sb.Append($"——{OiInfo.MName}—{l[0]}\r\n");
                }
                else
                {
                    sb.Append("\r\n");
                }
                Oiname = OiInfo.MName;
            }
            else
            {
                sb.Append("\r\n");
            }
            return sb.ToString();
        }
        public static string Analysis()
        {
            StringBuilder sb = new StringBuilder();

            return sb.ToString();
        }
        public static string AnalysisAPDU(byte[] frame, int lenPoint)
        {
            //analysisPoint = 18;
            analysisPoint = lenPoint;
            if (analysisPoint >= frame.Length)
            {
                return null;
            }
            StringBuilder sb = new StringBuilder();
            sb.Append("--------解析--------\r\n");
            switch (frame[analysisPoint++])
            {
                case 0x82:
                    sb.Append("预连接响应\r\n");
                    sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                    sb.Append(Analysis_Connect(frame));
                    break;
                case 0x83:
                    sb.Append("断开应用连接响应\r\n");
                    sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                    sb.Append(Analysis_DisConnect(frame));
                    break;
                //读取服务
                case 0x85:
                    switch (frame[analysisPoint++])
                    {
                        case 1:
                            sb.Append("读取一个对象属性的响应\r\n");
                            sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                            sb.Append(Analysis_Response(frame, 0x85));
                            break;
                        case 2:
                            sb.Append("读取若干个对象属性的响应\r\n");
                            sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                            int num = frame[analysisPoint++];
                            sb.Append($"共有{num}个对象属性及其数据\r\n");
                            for (int i = 0; i < num; i++)
                            {
                                sb.Append($"第{i + 1}个对象属性及其数据\r\n");
                                sb.Append(Analysis_Response(frame, 0x85));
                            }
                            break;
                         case 3:
                            sb.Append("读取一个记录型对象属性的响应\r\n");
                            sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                            sb.Append(Analysis_Record(frame));
                            break;
                        default:
                            break;
                    }
                    break;
                case 0x86:
                    switch (frame[analysisPoint++])
                    {
                        case 1:
                            sb.Append("设置一个对象属性的确认信息响应\r\n");
                            sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                            sb.Append(Analysis_Response(frame, 0x86));
                            break;
                        case 2:
                            sb.Append("设置若干个对象属性的确认信息响应\r\n");
                            sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                            int num = frame[analysisPoint++];
                            sb.Append($"共有{num}个对象属性及其数据\r\n");
                            for (int i = 0; i < num; i++)
                            {
                                sb.Append($"第{i + 1}个对象属性及其数据\r\n");
                                sb.Append(Analysis_Response(frame, 0x86));
                            }

                            break;
                        default:
                            break;
                    }
                    break;
                case 0x87:
                    switch (frame[analysisPoint++])
                    {
                        case 1:
                            sb.Append("设置一个对象属性的确认信息响应\r\n");
                            sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                            sb.Append(Analysis_Response(frame, 0x87));
                            break;
                        case 2:
                            sb.Append("设置若干个对象属性的确认信息响应\r\n");
                            sb.Append("服务序号-优先级-ACD:" + frame[analysisPoint++].ToString("X2") + "\r\n");
                            int num = frame[analysisPoint++];
                            sb.Append($"共有{num}个对象属性及其数据\r\n");
                            for (int i = 0; i < num; i++)
                            {
                                sb.Append($"第{i + 1}个对象属性及其数据\r\n");
                                sb.Append(Analysis_Response(frame, 0x86));
                            }

                            break;
                        default:
                            break;
                    }
                    break;
                case 0x90:
                    string mac;
                    string cTaskData;
                    string outData;
                    StateGridClient sc = ServiceLocator.Current.GetInstance<MainViewModel>().sc;
                    switch (frame[analysisPoint++])
                    {
                        case 0:
                            sb.Append("明文应用数据单元\r\n");
                            int apduLen = frame[analysisPoint++];
                            cTaskData = "";
                            for (int i = 0; i < apduLen; i++)
                            {
                                cTaskData += frame[analysisPoint + i].ToString("X2");
                            }
                            sb.Append(AnalysisAPDU(frame, analysisPoint));

                            if (frame[analysisPoint++] == 0x00)
                            {
                                sb.Append("无数据验证信息\r\n");
                            }
                            else
                            {
                                if (frame[analysisPoint++] == 0x00)
                                {
                                    sb.Append("数据MAC:");
                                    int macLen = frame[analysisPoint++];
                                    mac = "";
                                    for (int i = 0; i < macLen; i++)
                                    {
                                        mac += frame[analysisPoint++].ToString("X2");
                                        // sb.Append(frame[analysisPoint++].ToString("X2"));

                                    }
                                    sb.Append(mac + "\r\n");

                                    if (sc.Obj_Meter_Formal_VerifyMeterData(1, 1, "", AppControlViewModel.SessionInitKey, cTaskData, mac, out outData) == 0)
                                    {

                                        sb.Append("电表明文MAC验证成功\r\n");
                                    }
                                    sb.Append("\r\n");
                                }
                            }
                            break;
                        case 1:
                            sb.Append("密文应用数据单元\r\n");
                            apduLen = frame[analysisPoint++];
                            cTaskData = "";
                            for (int i = 0; i < apduLen; i++)
                            {
                                cTaskData += frame[analysisPoint + i].ToString("X2");
                            }
                            sb.Append($"密文数据_{apduLen}_{cTaskData}\r\n");
                            if (frame[analysisPoint + apduLen] == 1)
                            {
                                analysisPoint++;
                                if (frame[analysisPoint + apduLen] == 0)
                                {
                                    analysisPoint++;
                                    int macLen = frame[apduLen + analysisPoint++];
                                    mac = "";
                                    for (int i = 0; i < macLen; i++)
                                    {
                                        mac += frame[apduLen + analysisPoint++].ToString("X2");

                                    }
                                    sb.Append($"数据MAC:MAC_{macLen}_{mac}\r\n");
                                }
                            }
                            if (sc.Obj_Meter_Formal_VerifyMeterData(1, 2, "", AppControlViewModel.SessionInitKey, cTaskData, "", out outData) == 0)
                            {
                                sb.Append("解密后的APDU明文\r\n");
                                sb.Append(AnalysisAPDU(StringUtils.hexStringToBytes(outData), 0));
                            }
                            break;
                        case 2:
                            sb.Append($"异常错误:{frame[analysisPoint++]}\r\n");

                            break;
                        default:
                            break;
                    }
                    return sb.ToString();
                default:
                    break;
            }
            if (frame[analysisPoint++] == 0)
            {
                sb.Append("无跟随上报信息域\r\n");
            }
            else
            {
                sb.Append("有跟随上报信息域\r\n");
            }
            if (frame[analysisPoint++] == 0)
            {
                sb.Append("没有时间标签\r\n");
            }
            else
            {
                sb.Append("有时间标签\r\n");
            }
            return sb.ToString();
        }
        public static string AnalysisData(byte[] frame, string OIName, string OAD)
        {
            StringBuilder sb = new StringBuilder();
            int dataNum;
            string result = "";
            string oi;
            string temp = "";
            int data32 = 0;
            Int16 data16 = 0;
            Int64 data64 = 0;
            switch (frame[analysisPoint++])
            {
                case 0:

                    sb.Append("NULL\r\n"); ;
                    break;
                case 1:
                    dataNum = frame[analysisPoint++];
                    if (1 == 0 && OIName.Contains("功电能") || OIName.Contains("需量"))
                    {
                        for (int i = 0; i < dataNum; i++)
                        {
                            //switch()
                            if (i == 0)
                            {
                                sb.Append("总：");
                            }
                            else if (i == 1)
                            {
                                sb.Append("费率1：");
                            }
                            else if (i == 2)
                            {
                                sb.Append("费率2：");
                            }
                            else if (i == 3)
                            {
                                sb.Append("费率3：");
                            }
                            else if (i == 4)
                            {
                                sb.Append("费率4：");
                            }
                            sb.Append(AnalysisData(frame, OIName, OAD) + "\r\n");
                        }
                    }
                    else
                    {
                        sb.Append($"{dataNum}个元素(array)\r\n");
                        for (int i = 0; i < dataNum; i++)
                        {
                            sb.Append($"array-{i + 1}\r\n");
                            sb.Append(AnalysisData(frame, OIName, OAD) + "\r\n");

                        }
                    }
                    break;
                case 2:
                    int structureNum = frame[analysisPoint++];
                    sb.Append($"{structureNum}个元素(structure)\r\n");
                    sb.Append("{");
                    for (int i = 0; i < structureNum; i++)
                    {
                        if (OAD.Equals("F1000700") && i == 0)
                        {
                            temp = AnalysisData(frame, OIName, OAD);
                            AppControlViewModel.ESAMCounter = temp;
                            sb.Append(temp + "\r\n");
                        }
                        else
                        {
                            sb.Append(AnalysisData(frame, OIName, OAD) + "\r\n");
                        }
                    }
                    sb.Append("}\r\n");
                    break;
                case 4:
                    int bitNum = frame[analysisPoint++];
                    switch (bitNum / 8)
                    {
                        case 2:
                            data16 = BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                            sb.Append($"0x{data16.ToString("X4")}");
                            analysisPoint += 2;
                            break;
                        case 4:
                            data32 = BitConverter.ToInt32(new byte[] { frame[analysisPoint + 3], frame[analysisPoint + 2], frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                            sb.Append($"0x{data32.ToString("X8")}");
                            analysisPoint += 4;
                            break;
                        default:
                            break;
                    }
                    break;
                case 5:
                case 6:
                    string unit = "";

                    int demi = 0;

                    if (OIName.Contains("电能"))
                    {
                        if (OIName.Contains("无功"))
                        {
                            unit = "kvarh";
                        }
                        else if (OIName.Contains("有功"))
                        {
                            unit = "kWh";
                        }
                        demi = 2;
                    }
                    else if (OIName.Contains("需量"))
                    {
                        if (OIName.Contains("无功"))
                        {
                            unit = "kvar";
                        }
                        else if (OIName.Contains("有功"))
                        {
                            unit = "kw";
                        }
                        demi = 4;
                    }

                    data32 = BitConverter.ToInt32(new byte[] { frame[analysisPoint + 3], frame[analysisPoint + 2], frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                    analysisPoint += 4;
                    switch (demi)
                    {
                        case 2:
                            result = string.Format("{0:f2}{1}", data32 / 100.0, unit);
                            break;
                        case 4:
                            result = string.Format("{0:f4}{1}", data32 / 10000.0, unit);
                            break;
                        default:
                            result = string.Format("{0}{1}", data32, unit);
                            break;
                    }

                    sb.Append(result);
                    break;
                case 9:
                    int byteNum = frame[analysisPoint++];

                    /*for (int i = 0; i < 4; i++)
                    {
                        OAD += frame[analysisPoint - 7 + i].ToString("X2");
                    }*/
                    temp = "";
                    for (int i = 0; i < byteNum; i++)
                    {
                        temp += frame[analysisPoint + i].ToString("X2");
                    }
                    if (OAD.Equals("F1000200"))
                    {
                        AppControlViewModel.ESAMDiv = temp;
                    }
                    else if (OAD.Equals("F1000400"))
                    {
                        AppControlViewModel.ESAMVersion = temp;
                    }
                    result = "0x" + temp;

                    analysisPoint += byteNum;
                    sb.Append(result); ;
                    break;
                case 3:
                case 0x0a:
                    int asciiNum = frame[analysisPoint++];

                    for (int i = 0; i < asciiNum; i++)
                    {
                        result += (char)frame[analysisPoint + i];

                    }
                    //result=StringUtils.asciiToString(temp);
                    sb.Append(result); ;
                    break;
                case 0x11:
                    sb.Append(frame[analysisPoint].ToString());
                    analysisPoint += 1;
                    break;
                case 0x10:
                case 0x12:
                    data16 = BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                    analysisPoint += 2;
                    sb.Append(data16.ToString()); ;
                    break;
                case 0x14:
                case 0x15:
                    unit = "";

                    demi = 0;

                    if (OIName.Contains("电能"))
                    {
                        if (OIName.Contains("无功"))
                        {
                            unit = "kvarh";
                        }
                        else if (OIName.Contains("有功"))
                        {
                            unit = "kWh";
                        }
                        demi = 2;
                    }
                    else if (OIName.Contains("需量"))
                    {
                        if (OIName.Contains("无功"))
                        {
                            unit = "kvar";
                        }
                        else if (OIName.Contains("有功"))
                        {
                            unit = "kw";
                        }
                        demi = 4;
                    }
                    data64 = BitConverter.ToInt64(new byte[] { frame[analysisPoint + 7], frame[analysisPoint + 6], frame[analysisPoint + 5], frame[analysisPoint + 4], frame[analysisPoint + 3], frame[analysisPoint + 2], frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                    analysisPoint += 8;
                    result = string.Format("{0:f4}{1}", data64 / 10000.0, unit);
                    sb.Append(result);
                    break;
                case 0x16:
                    //analysisPoint += 1;
                    sb.Append(frame[analysisPoint++].ToString()); ;
                    break;
                case 0x1c:
                    byte[] byteYear = new byte[2];
                    byteYear[0] = frame[analysisPoint];
                    byteYear[1] = frame[analysisPoint + 1];
                    short year = ByteUtils.hBytesToShort(byteYear);
                    string dateTime = string.Format("{0:d4}年{1:d2}月{2:d2}日{3:d2}时{4:d2}分{5:d2}秒", year, frame[analysisPoint + 2], frame[analysisPoint + 3],
                        frame[analysisPoint + 4], frame[analysisPoint + 5], frame[analysisPoint + 6]);
                    analysisPoint += 7;
                    sb.Append(dateTime.ToString());
                    break;
                case 0x50:
                    sb.Append($"对象标识：{frame[analysisPoint].ToString("X2") + frame[analysisPoint + 1].ToString("X2")}");
                    analysisPoint += 2;
                    break;
                case 0x51:
                    oi = frame[analysisPoint].ToString("X2") + frame[analysisPoint + 1].ToString("X2");
                    sb.Append($"对象属性描述符：{oi + frame[analysisPoint + 2].ToString("X2") + frame[analysisPoint + 3].ToString("X2")}——{oIService.SelectNameByOI(oi).MName}");
                    analysisPoint += 4;
                    break;
                case 0x55:
                    //TSA
                    sb.Append("目标服务器地址TSA:");
                    for (int i = 0; i < frame[analysisPoint+1]+1; i++)
                    {
                        sb.Append(frame[analysisPoint + 1+i+1].ToString("X2"));
                    }
                    analysisPoint += frame[analysisPoint]+1;
                    break;
                case 0x59:
                    string s = frame[analysisPoint++].ToString("X2");
                    var d = Convert.ToSByte(s, 16);
                    sb.Append("换算：" + d.ToString() + "\r\n");
                    sb.Append("单位：" + enumInfoService.SelectUnit(Convert.ToSByte(frame[analysisPoint++].ToString("X2"), 16)));
                    break;
                case 0x5B:

                    oi = frame[analysisPoint + 1].ToString("X2") + frame[analysisPoint + 2].ToString("X2");
                    sb.Append($"对象属性描述符：{oi + frame[analysisPoint + 3].ToString("X2") + frame[analysisPoint + 4].ToString("X2")}——{oIService.SelectNameByOI(oi).MName}");
                    analysisPoint += 5;

                    break;
                default:
                    break;
            }
            return sb.ToString();
        }
        private static string Analysis_Response(byte[] frame, byte frameType)
        {
            StringBuilder sb = new StringBuilder();
            //OAD
            sb.Append("对象属性描述符：");
            string OI = "";
            string OAD = "";
            int attributeID = 0;
            int index = 0;
            int rValue = -1;
            string Oiname = "";
            for (int i = 0; i < 4; i++)
            {
                if (i < 2)
                {
                    OI += frame[analysisPoint].ToString("X2");
                }
                else if (i == 2)
                {
                    attributeID = frame[analysisPoint];
                }
                else
                {
                    index = frame[analysisPoint];
                }
                OAD += frame[analysisPoint].ToString("X2");
                sb.Append(frame[analysisPoint].ToString("X2"));
                analysisPoint++;
            }

            //SqlSugarHelper.Db.Queryable<ObjectID>().Where(o => o._ObjectID == OI);
            var OiInfo = oIService.SelectNameByOI(OI);
            if (OiInfo != null)
            {
                var l = SqlSugarHelper.Db.Queryable<ClassAttribute>().Where(c => c.MAttribute == attributeID).Where(c => c.MClass == OiInfo.MIC).Select(c => c.MName).ToList();
                if (l.Count > 0)
                {
                    sb.Append($"——{OiInfo.MName}—{l[0]}\r\n\r\n其结果:");
                }
                else
                {
                    sb.Append("\r\n\r\n其结果:");
                }
                Oiname = OiInfo.MName;
            }
            else
            {
                sb.Append("\r\n\r\n其结果:");
            }

            switch (frameType)
            {

                case 0x85:
                    //Get-Result∷=CHOICE
                    if (frame[analysisPoint++] == 0)
                    {
                        rValue = frame[analysisPoint++];
                        sb.Append($"{dataAccessResultService.Select(rValue)}        {rValue}\r\n");

                    }
                    else
                    {
                        sb.Append(AnalysisData(frame, Oiname, OAD) + "\r\n");
                    }
                    break;
                case 0x83:
                case 0x87:
                case 0x86:
                    //设置执行结果
                    rValue = frame[analysisPoint++];
                    sb.Append($"{dataAccessResultService.Select(rValue)}        {rValue}\r\n");
                    break;
                default:
                    break;
            }


            return sb.ToString();
        }
        private static string Analysis_Record(byte[] frame)
        {
            StringBuilder sb = new StringBuilder();
            int rValue = -1;
            //记录型对象属性描述符    	OAD
            sb.Append(GetOADInfo(frame)+"\r\n");
            
            //一行记录N列属性描述符 	RCSD
            int CSDNum = frame[analysisPoint++];
            for (int i = 0; i < CSDNum; i++)
            {
                switch (frame[analysisPoint++])
                {
                    case 0:
                        //OAD
                        sb.Append(GetOADInfo(frame) + "\r\n");
                        break;
                    case 1:
                        //ROAD
                        sb.Append("记录型对象属性描述符：\r\n");
                        sb.Append(GetOADInfo(frame));
                        sb.Append("关联对象属性描述符：\r\n");
                        int OADNum = frame[analysisPoint++];
                        for (int j = 0; j < OADNum; j++)
                        {
                            sb.Append(GetOADInfo(frame));
                        }
                        sb.Append("\r\n");
                        break;
                    default:
                        break;
                }
            }


            //响应数据                  CHOICE
            sb.Append("响应数据\r\n");
            if (frame[analysisPoint++] == 0)
            {
                rValue = frame[analysisPoint++];
                sb.Append($"{dataAccessResultService.Select(rValue)}        {rValue}\r\n");

            }
            else
            {
                int recordRowNum = frame[analysisPoint++];
                sb.Append($"{recordRowNum}条记录\r\n");
                for (int i = 0; i < recordRowNum; i++)
                {
                    sb.Append($"第{i+1}条记录\r\n");
                    for (int CSDNum_i = 0; CSDNum_i < CSDNum; CSDNum_i++)
                    {
                        sb.Append($"第{CSDNum_i+1}列数据：");
                        sb.Append(AnalysisData(frame, "", "") + "\r\n");
                    }
                    
                }
               
            }
            return sb.ToString();
        }
        private static string Analysis_Connect(byte[] frame)
        {
            StringBuilder sb = new StringBuilder();
            try
            {
                string temp;
                Int32 data32;
                Int16 data16;
                int result = 0;
                int num = 0;
                sb.Append("厂商代码:");
                for (int i = 0; i < 4; i++)
                {
                    sb.Append((char)frame[analysisPoint++]);
                }
                sb.Append("\r\n软件版本号:");
                for (int i = 0; i < 4; i++)
                {
                    sb.Append((char)frame[analysisPoint++]);
                }
                sb.Append("\r\n软件版本日期:");
                for (int i = 0; i < 6; i++)
                {
                    sb.Append((char)frame[analysisPoint++]);
                }
                sb.Append("\r\n硬件版本号:");
                for (int i = 0; i < 4; i++)
                {
                    sb.Append((char)frame[analysisPoint++]);
                }
                sb.Append("\r\n硬件版本日期:");
                for (int i = 0; i < 6; i++)
                {
                    sb.Append((char)frame[analysisPoint++]);
                }
                sb.Append("\r\n厂家扩展信息:");
                for (int i = 0; i < 8; i++)
                {
                    sb.Append((char)frame[analysisPoint++]);
                }
                sb.Append("\r\n商定的应用层协议版本号:");
                data16 = BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                analysisPoint += 2;
                sb.Append(data16.ToString("X4"));
                sb.Append("\r\n商定的协议一致性块:0x");
                for (int i = 0; i < 8; i++)
                {
                    sb.Append(frame[analysisPoint++].ToString("X2"));
                }
                sb.Append("\r\n商定的功能一致性块:0x");
                for (int i = 0; i < 16; i++)
                {
                    sb.Append(frame[analysisPoint++].ToString("X2"));
                }
                sb.Append("\r\n服务器发送帧最大尺寸:");
                data16 = BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                analysisPoint += 2;
                sb.Append(data16.ToString());
                sb.Append("\r\n服务器接收帧最大尺寸:");
                data16 = BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                analysisPoint += 2;
                sb.Append(data16.ToString());
                sb.Append($"\r\n服务器接收帧最大窗口尺寸:{frame[analysisPoint++]}");
                sb.Append("\r\n服务器最大可处理APDU尺寸:");
                data16 = BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                analysisPoint += 2;
                sb.Append(data16.ToString());
                sb.Append("\r\n商定的应用连接超时时间:");
                data32 = BitConverter.ToInt32(new byte[] { frame[analysisPoint + 3], frame[analysisPoint + 2], frame[analysisPoint + 1], frame[analysisPoint] }, 0);
                analysisPoint += 4;
                sb.Append(data32.ToString());
                result = frame[analysisPoint++];
                sb.Append($"\r\n认证结果:{result}\r\n***允许建立应用连接(0)，密码错误(1)，对称解密错误(2)，非对称解密错误(3)，签名错误(4)，协议版本不匹配(5)，其他错误(255)\r\n");
                if (frame[analysisPoint++] == 0)
                {
                    sb.Append("\r\n无认证附加信息\r\n");
                }
                else
                {
                    num = frame[analysisPoint++];
                    sb.Append("\r\n认证附加信息:{\r\n" + $"服务器随机数_{num}_");
                    temp = "";
                    for (int i = 0; i < num; i++)
                    {
                        temp += frame[analysisPoint++].ToString("X2");
                        //sb.Append(frame[analysisPoint++].ToString("X2"));
                    }
                    sb.Append(temp);
                    AppControlViewModel.SessionInit = temp;
                    num = frame[analysisPoint++];
                    sb.Append("\r\n" + $"服务器签名信息_{num}_");
                    temp = "";
                    for (int i = 0; i < num; i++)
                    {
                        temp += frame[analysisPoint++].ToString("X2");
                    }
                    sb.Append(temp);
                    AppControlViewModel.Sign = temp;
                    sb.Append("\r\n}\r\n");
                }
                if (frame[analysisPoint++] == 0)
                {
                    sb.Append("无跟随上报信息域\r\n");
                }
                else
                {
                    sb.Append("有跟随上报信息域\r\n");
                }
                if (frame[analysisPoint++] == 0)
                {
                    sb.Append("没有时间标签\r\n");
                }
                else
                {
                    sb.Append("有时间标签\r\n");
                }
                return sb.ToString();
            }
            catch (Exception)
            {
                return sb.ToString()+"解析失败\r\n";
            }
            
        }

        private static string Analysis_DisConnect(byte[] frame)
        {
            StringBuilder sb = new StringBuilder();
            int rValue = frame[analysisPoint++];
            if (rValue==0)
            {
                AppControlViewModel.SessionInitKey = "";
            }
            sb.Append($"结果:{dataAccessResultService.Select(rValue)}        {rValue}\r\n");
            return sb.ToString();
        }

        public static GPRSInfo AnalysisGPRSLogin(byte[] frame,ref Enums.LinkEnum linkEnum)
        {
            //68 1E 00 81 05 06 00 00 26 08 20 00 F2 50 01 25 00 01 2C 07 E8 02 02 05 09 1C 30 00 A5 E3 1A 16
            GPRSInfo gPRSInfo = new GPRSInfo();
            string temp="";
            
            analysisPoint = 4;
            for (int i = frame[analysisPoint] + 1; i >0; i--)
            {
                temp += frame[analysisPoint+i].ToString("X2");
            }
            
            gPRSInfo.Address = temp;
            analysisPoint += frame[analysisPoint] + 1+1;
            analysisPoint += 3;
            //LINK-Request
            if (frame[analysisPoint++]==0x01)
            {
                
                MessageGenerationModule.SetPIID(frame[analysisPoint++]);
                switch (frame[analysisPoint++])
                {
                    //登录
                    case 0:
                        linkEnum = Enums.LinkEnum.Login;
                        break;
                    //心跳
                    case 1:
                        linkEnum = Enums.LinkEnum.Heart;
                        break;
                    default:
                        break;
                }
                gPRSInfo.HeartCycleTime = BitConverter.ToInt16(new byte []{ frame[analysisPoint+1], frame[analysisPoint] },0);
                analysisPoint += 2;
                if (linkEnum== Enums.LinkEnum.Login)
                {
                    gPRSInfo.LoginDateTime = new DateTime(BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0)
                     , frame[analysisPoint + 2], frame[analysisPoint + 3], frame[analysisPoint + 5], frame[analysisPoint + 6], frame[analysisPoint + 7]
                     , BitConverter.ToInt16(new byte[] { frame[analysisPoint + 9], frame[analysisPoint+8] }, 0));
                }
                gPRSInfo.HeartDateTime = new DateTime(BitConverter.ToInt16(new byte[] { frame[analysisPoint + 1], frame[analysisPoint] }, 0)
                     , frame[analysisPoint + 2], frame[analysisPoint + 3], frame[analysisPoint + 5], frame[analysisPoint + 6], frame[analysisPoint + 7]
                     , BitConverter.ToInt16(new byte[] { frame[analysisPoint + 9], frame[analysisPoint + 8] }, 0));
                
            }
            else
            {
                return null;
            }
            return gPRSInfo;
        }
    }
}
